package cn.hicard.risk.action.bd;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import cn.hicard.risk.common.Constant;
import cn.hicard.core.Page;
import cn.hicard.core.PageResult;
import cn.hicard.core.Where;
import cn.hicard.risk.entity.BdBankcall;
import cn.hicard.risk.entity.RiskLimitFreeze;
import cn.hicard.risk.interf.bankcall.BankcallTransInfoInterf;
import cn.hicard.risk.interf.bankcall.BankcallTransInfoVO;
import cn.hicard.risk.interf.limit.FreezeInfoInterf;
import cn.hicard.risk.interf.limit.RiskLimitFreezeInterface;
import cn.hicard.risk.report.ReportTemplet;
import cn.hicard.risk.service.bd.BankcallService;
import cn.hicard.risk.service.bd.RiskLimitFreezeService;
import cn.hicard.util.DataTran;
import cn.hicard.util.DateHelp;

public class BankcallFlex {

	private static Logger logger = Logger.getLogger(Constant.LOGGER_MAIN);
	
	/**银行调单信息业务类*/
	private BankcallService bankcallService;
	/**额度冻结信息业务类 */
	private RiskLimitFreezeService riskLimitFreezeService;
	
	public void setBankcallService(BankcallService bankcallService) {
		this.bankcallService = bankcallService;
	}
	
	public void setRiskLimitFreezeService(
			RiskLimitFreezeService riskLimitFreezeService) {
		this.riskLimitFreezeService = riskLimitFreezeService;
	}


	/**
	 * 查询分页
	 * @param bankcallStart
	 * @param bankcallEnd
	 * @param page
	 * @return
	 * @throws Exception
	 */
	public PageResult<BdBankcall> search(BdBankcall bankcallStart,BdBankcall bankcallEnd,Page page) throws Exception{
		
		//查询
		try {
			return bankcallService.search(bankcallStart,bankcallEnd,page);
		} catch (Exception e) {
			logger.error("搜索时发生异常",e);
			throw e;
		}
	}
	/**
	 * 查询列表信息
	 * @param bankcallStart
	 * @param bankcallEnd
	 * @return
	 * @throws Exception
	 */
	public List<BdBankcall> findReportList(BdBankcall bankcallStart,BdBankcall bankcallEnd) throws Exception{
		return bankcallService.findList(bankcallStart, bankcallEnd);
	}
	
	/**
	 * 新增调单信息
	 * @throws Exception 
	 */
	public void saveBankcall(BdBankcall bankcall) throws Exception{
		try {
			bankcallService.save(bankcall);
		} catch (Exception e) {
			logger.error("新增银行调单信息出错", e);
			throw e;
		}
	}
	
	/**
	 * 修改调单信息
	 * @throws Exception 
	 */
	public void modifyBankcall(BdBankcall bankcall) throws Exception{
		try {
			bankcallService.update(bankcall);
		} catch (Exception e) {
			logger.error("修改银行调单信息出错", e);
			throw e;
		}
	}
	
	/**
	 * 下载银行调单报表
	 * @param start
	 * @param end
	 * @return
	 */
	public byte[] downloadReport(BdBankcall start, BdBankcall end){		
		// 查询数据
		List<BdBankcall> list = null;
		try {
			list = findReportList(start, end);
		} catch (Exception e) {
			logger.error("",e);
		}
		if(list == null){
			list = new  ArrayList<BdBankcall>();
		}
		
		// 构建报表
		ReportTemplet rt = new ReportTemplet();
		
		String title = "银行调单明细报表";
		String descrip = "条件：共计 " 
							  + list.size() 
							  + " 条，报表下载时间： " + DateHelp.dateTime();
		
		String[] fields = new String[]{
				"汇卡商户号","商户名称","银联商户号","订单号","系统参考号","授权码",
				"交易时间","交易金额（单位/元）","交易卡号",
				"是否止付","状态","扣款金额","扣款时间","是否锁定","销账时间",
				"是否解冻","解冻时间","备注"};
		List<Object[]> source = new ArrayList<Object[]>();		
		// 组装数据
		for (BdBankcall item:list) {	
			String isUnfreeze = "否";
			if(item.getStatus()!=null&& "5".equals(item.getStatus())){
				isUnfreeze = "是";
			}
			
			source.add(new Object[]{
					item.getHmid(),
					item.getMerchname(),
					item.getOmid(),
					item.getOrderno(),
					item.getSysno(),
					item.getAuthcode(),
					item.getTranstime(),
					item.getTransamount(),
					item.getCardno(),
					changeStopType(item.getStatus()),//是否止付 
					changeStatusType(item.getStatus()),//状态
					item.getDeductamount(),
					item.getDeducttime(),
					changeLockType(item.getStatus()),//是否锁定
					item.getCanceltime(),
					isUnfreeze,
					item.getUnfreezetime(),
		            item.getRemark()
					});
		}
		ByteArrayOutputStream bos = rt.createGeneralTemplet(title, descrip, fields, source);
		return bos.toByteArray();
	}
	
	//查询交易信息
	public List<BdBankcall> searchTransinfo(BdBankcall bankcall) throws Exception{
		
		BankcallTransInfoVO infoVO = new BankcallTransInfoVO();
		infoVO.setAuthNo(bankcall.getAuthcode());
		infoVO.setSysNo(bankcall.getSysno());
		infoVO.setOrderId(bankcall.getOrderno());
		infoVO.setCardNo(bankcall.getCardno());
		
		//通过接口或导入交易数据后查询。。。。
		BankcallTransInfoInterf interf = new BankcallTransInfoInterf();
		List<BankcallTransInfoVO> retList = null;
		retList	= interf.seachTransInfo(infoVO,Constant.INTERF_BANKCALL_TRANSINFO);
		List<BdBankcall> list = new ArrayList<BdBankcall>();
		if(retList!=null){
			for(int i=0;i<retList.size();i++){
				BankcallTransInfoVO retVO = retList.get(i);
				bankcall.setAuthcode(retVO.getAuthNo());
				bankcall.setSysno(retVO.getSysNo());
				bankcall.setOrderno(retVO.getOrderId());
				bankcall.setHmid(retVO.getHmId());
				bankcall.setOmid(retVO.getOmId());
				bankcall.setMerchname(retVO.getHmName());
				bankcall.setOtid(retVO.getOtId());
				//bankcall.setCardno(DataTran.shieldingCardno(retVO.getCardNo()));//屏蔽卡号
				bankcall.setCardno(retVO.getCardNo());
				bankcall.setTransamount(DataTran.longToStr(retVO.getTransAmount()));//交易金额
				bankcall.setReckamount(DataTran.longToStr(retVO.getReckAmount()));//清算金额
				bankcall.setTranstime(retVO.getTransTime());
				//bankcall.setDeductamount(DataTran.longToStr(retVO.getReckAmount()));//扣款金额(清算金额/实际冻结金额)
				bankcall.setTranstime(retVO.getTransTime());
				bankcall.setOrgno(retVO.getOrgNo());
				
				list.add(bankcall);
		  }
		
		}
		
		return list;
	}
	
	
	
	/**
	 * 修改信息状态
	 * 调用接口发送冻结/解冻/销账信息
	 * @throws Exception 
	 */
	public boolean changeStatus(BdBankcall bankcall,String optCode) throws Exception{
		
		// 页面操作标志 1冻结/2解冻审核/3解冻复核/4 解冻复核未通过 /5锁定/6解锁审核 /7解锁复核/8解锁复核未通过
		
		// 风控status 1待冻结/2部分冻结/3已冻结/4解冻待复核/5已解冻/6已锁定/7解锁已初审/(多余8已解锁)/9已止付
		boolean flag = true;
		BdBankcall rebankcall = null;//调用接口发法返回对象
		String freezeTimeStr = DateHelp.dateNumber();//yyyyMMddHHmmss
		String timeStr = DateHelp.numberToDate(freezeTimeStr);//yyyy-MM-dd HH:mm:ss
		
		try {
             //冻结
			if (optCode != null && "1".equals(optCode)) {
				// 通知清算进行冻结
				bankcall.setStatus("1");
				bankcall.setBankfreezeId(bankcall.getHmid() + freezeTimeStr);//唯一标识码
				bankcall.setDeducttime(timeStr);//冻结时间
				
				rebankcall = sendBankcallInfo(bankcall);
				bankcall.setStatus(rebankcall.getStatus());//部分冻结2或已冻结3
				
                if("1".equals(rebankcall.getStatus())){
					logger.info("可冻金额不足，清算系统未成功冻结！");
					bankcall.setExplanation("止付成功，该商户可冻金额不足，清算系统已将其设为待冻结");
					bankcall.setStatus("9");//9已进行过止付操作
				}
				
				bankcall.setDeductamount(rebankcall.getDeductamount());
			
			//解冻审核
			} else if ("2".equals(optCode)) {
				// 仅修改风控状态
				bankcall.setStatus("4");// 解冻待复核
				
			//解冻复核通过
			} else if ("3".equals(optCode)) {
				// 通知清算进行解冻
				bankcall.setStatus("4");//解冻待复核
				bankcall.setUnfreezetime(timeStr);//解冻时间
				rebankcall = sendBankcallInfo(bankcall);
				bankcall.setStatus(rebankcall.getStatus());
				bankcall.setExplanation("");//将冻结说明清空
			}
			
			//解冻复核未通过
			else if("4".equals(optCode)){
				//解冻复核不通过，恢复到审核前状态
				if(bankcall.getReckamount().equals(bankcall.getDeductamount())){
					bankcall.setStatus("3");
				}else{
					bankcall.setStatus("2");
				}
				
			}
			//进行锁定
			else if("5".equals(optCode)){
	
			     bankcall.setStatus("6");// 已锁定
			     bankcall.setCanceltime(timeStr);
			
			}
			//解锁初审
			else if ("6".equals(optCode)) {
				// 仅修改风控状态
				bankcall.setStatus("7");// 解锁待复核

			} 
			//解锁复审通过
			else if ("7".equals(optCode)) {

				if(bankcall.getReckamount().equals(bankcall.getDeductamount())){
					bankcall.setStatus("3");// 解锁待复核->已解锁(已冻结)
				}else{
					bankcall.setStatus("2");// 解锁待复核->已解锁(已冻结)
				}
				
				bankcall.setCanceltime(timeStr);
		
			}
			//解锁复审未通过
			else if("8".equals(optCode)){
				//解锁复核不通过，恢复到审核前状态
				bankcall.setStatus("6");//恢复到 已锁定
				
			}
			
		} catch (Exception e) {
			logger.error("调用接口发送冻结/解冻/销账信息时出错", e);
			flag = false;
		}
		
		try {
			modifyBankcall(bankcall);
		} catch (Exception e) {
			logger.error("银行调单保存清算返回信息时出错", e);
			flag = false;
		}
		
		return flag;
	}
	
	/**
	 * 调用与新清算接口发送冻结/解冻信息 并保存返回的状态
	 * 
	 * @throws Exception
	 */
	public BdBankcall sendBankcallInfo(BdBankcall bankcall) throws Exception {

		RiskLimitFreezeInterface interVo = new RiskLimitFreezeInterface();
		interVo.setHmId(bankcall.getHmid());// 汇卡商户号
		interVo.setMerchName(bankcall.getMerchname());// 商户名
		   
		long moneyLong = DataTran.strToLong(bankcall.getReckamount());//纠正为 清算金额
		
		interVo.setFreezeMoney(moneyLong);// 应冻结/解冻金额

		interVo.setFreezeId(bankcall.getBankfreezeId());// 唯一标识ID

		interVo.setStatus(bankcall.getStatus());// 状态 1 待冻结/4解冻待复核/6销账待复核

		if ("1".equals(bankcall.getStatus())) {
			interVo.setFreezeTime(bankcall.getDeducttime());// 冻结时间

		} else if ("4".equals(bankcall.getStatus())) {
			interVo.setUnfreezeTime(bankcall.getUnfreezetime());// 解冻时间

		} else if ("6".equals(bankcall.getStatus())) {
			interVo.setUnfreezeTime(bankcall.getCanceltime());// 销账时间
		}

		FreezeInfoInterf interf = new FreezeInfoInterf();

		RiskLimitFreezeInterface returnInfo;
		try {
			//冻结金额为0时不再调用接口
			if(interVo.getFreezeMoney()!=0){
				returnInfo = interf.receiveSumMoney(interVo,
						Constant.INTERF_BANKCALL_SENDINFO);
				// 保存接口返回对象信息
				// 实际冻结金额（扣款金额）
				bankcall.setDeductamount(DataTran.longToStr(returnInfo
						.getFreezeAmounted()));
				bankcall.setStatus(returnInfo.getStatus());// 清算返回的状态
				// bankcall.setDeducttime(timeStr);// 扣款时间
			}
		
		} catch (Exception e) {
			logger.error("与清算银行调单紧急止付接口出错", e);
			throw new Exception(e.getMessage());
		}

		return bankcall;

	}

	// 连清算库更新多条冻结数据(不用)
	public String updateBankFreezeInfo(BdBankcall bankcallStart,BdBankcall bankcallEnd) throws Exception {

			// 查询风控中 状态为 2部分冻结/3已冻结/4解冻待复核/6销账待复核 的数据

			Where where = new Where(BdBankcall.class);
			StringBuffer returnMsg = new StringBuffer();//返回给前台的错误信息
			
			if(bankcallStart!=null){
	    		where.addEqual("hmid", bankcallStart.getHmid());
	    		where.addLike("merchname", bankcallStart.getMerchname());
	    		where.addEqual("orderno", bankcallStart.getOrderno());
	    		where.addLike("orgno", bankcallStart.getOrgno());
	    		where.addEqual("type", bankcallStart.getType());
	    		where.addEqual("ischargeback", bankcallStart.getIschargeback());
	    		where.addEqual("transamount", bankcallStart.getTransamount());
	    	}
			if(bankcallEnd!=null){
				where.addBetween("transtime", bankcallStart.getTranstime(),bankcallEnd.getTranstime());	
				where.addBetween("informtime", bankcallStart.getInformtime(),bankcallEnd.getInformtime());	
				where.addBetween("returntime", bankcallStart.getReturntime(),bankcallEnd.getReturntime());
			}
			
			where.addIn("status", "0", "2", "4", "6");//0已止付/2部分冻结/4解冻待复核/6销账待复核
			List<BdBankcall> list = null;
			try {
				list = bankcallService.findListByWhere(where);
			} catch (Exception e) {
				logger.error("查询风控额度冻结信息时出错", e);
				returnMsg.append("查询风控额度冻结信息时出错\n");
			}

			if(list!=null){
				for (int i = 0; i < list.size(); i++) {

					BdBankcall bankcall = list.get(i);

					Where whereRisk = new Where(RiskLimitFreeze.class);
					whereRisk.addEqual("freezeId", bankcall.getBankfreezeId());
					List freezeInfoList = null;
					try {
						freezeInfoList = riskLimitFreezeService.findList(whereRisk);
					} catch (Exception e) {
						logger.error("查询新清算额度冻结信息时出错", e);
						returnMsg.append("查询新清算额度冻结信息时出错\n");
					}
					RiskLimitFreeze freezeInfo = null;
					 if(freezeInfoList!=null && freezeInfoList.size()!=0){
						 freezeInfo = (RiskLimitFreeze) freezeInfoList.get(0);
					 }
					
					if(freezeInfo!=null){
						if(freezeInfo.getFreezeAmount()== freezeInfo.getFreezeAmounted()){
							bankcall.setStatus("3");//全部冻结
						}else{
							//部分冻结、解冻待复核  更新冻结金额
							
							//实际冻结金额（扣款金额）
							bankcall.setDeductamount(DataTran.longToStr(freezeInfo.getFreezeAmounted()));//冻结金额
							bankcall.setDeducttime(freezeInfo.getFreezeTime());//冻结时间
							try {
								modifyBankcall(bankcall);
							} catch (Exception e) {
								logger.error("修改银行调单信息时出错", e);
								returnMsg.append("更新银行调单信息时出错\n");
							}
						}
					}
				}
				
			}
		return returnMsg.toString();
	}
	
	// 连清算库 查询单条额度冻结信息
	// 并更新风控表信息
	public BdBankcall updateSingleFreezeInfo(BdBankcall bankcall) throws Exception{
   
			Where whereRisk = new Where(RiskLimitFreeze.class);
			whereRisk.addEqual("freezeId", bankcall.getBankfreezeId());// 唯一标识一笔额度冻结(商户号+冻结时间)
			whereRisk.addEqual("status", "1");// 冻结
			RiskLimitFreeze freezeInfo = null;
			try {
				List freezeInfoList = riskLimitFreezeService.findList(whereRisk);
				if(freezeInfoList!=null && freezeInfoList.size()!=0){
					freezeInfo = (RiskLimitFreeze) freezeInfoList.get(0);
				}
			
			} catch (Exception e) {
				logger.error("查询新清算额度冻结信息时出错", e);
				throw new Exception(e.getMessage());
			}
			
			if (freezeInfo != null) {
				if (freezeInfo.getFreezeAmount() == freezeInfo.getFreezeAmounted()) {
					bankcall.setStatus("3");// 全部冻结
				} else if(freezeInfo.getFreezeAmounted()!=0L && (freezeInfo.getFreezeAmount() != freezeInfo.getFreezeAmounted())){
					bankcall.setStatus("2");// 部分冻结
					
				}else {
					logger.info("关联清算表，对唯一标识码为"+bankcall.getBankfreezeId()+"的冻结信息进行额度更新");
					// 部分冻结、解冻待复核、已止付  更新状态和冻结金额
					// 实际冻结金额（扣款金额）
					bankcall.setDeductamount(DataTran.longToStr(freezeInfo.getFreezeAmounted()));// 冻结金额
					bankcall.setDeducttime(freezeInfo.getFreezeTime());// 冻结时间
					
					try {
						modifyBankcall(bankcall);
					} catch (Exception e) {
						logger.error("查询新清算额度冻结信息并保存时出错", e);
						throw new Exception(e.getMessage());
					}
				}
			}
		return bankcall;
	}
	
	/**
	 * 数据字典转换
	 * @param type
	 * @return
	 */
	public static String changeShow(String type){
		String str = "";
		if(type==null){
			str = "";
		}else if("1".equals(type)){
			str = "查询";
		}else if("2".equals(type)){
			str = "调单";
		}else if("3".equals(type)){
			str = "其他";
		}	
		return str;
	}
	//止付状态
	public static String changeStopType(String type){
		String str = "";
		if(type==null){
			str = "";
		}else if("2".equals(type)||"3".equals(type)){
			str = "是";
		}else {
			str = "否";
		}
		return str;
	}
	
	//锁定状态
	public static String changeLockType(String type){
		String str = "";
		if(type==null){
			str = "";
		}else if("6".equals(type)){
			str = "是";
		}else{
			str = "否";
		}
		return str;
	}
	
	public static String changeStatusType(String type){
		//1待冻结/2部分冻结/3已冻结/4解冻待复核/5已解冻/6已锁定/7解锁已初审/8已解锁
		String str = "";
		if(type==null){
			str = "";
		}else if("0".equals(type)){
			str = "已止付";
		}else if("1".equals(type)){
			str = "待冻结";
		}else if("2".equals(type)){
			str = "部分冻结";
		}else if("3".equals(type)){
			str = "已冻结";
		}else if("4".equals(type)){
			str = "解冻待复核";
		}else if("5".equals(type)){
			str = "已解冻";
		}else if("6".equals(type)){
			str = "已锁定";
		}else if("7".equals(type)){
			str = "解锁已初审";
		}else if("8".equals(type)){
			str = "已解锁";
		}
		return str;
	}
}
